package me.flyray.crm.core.biz.customer;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import me.flyray.common.enums.FreezeStatus;
import me.flyray.common.exception.BusinessException;
import me.flyray.common.msg.BizResponseCode;
import me.flyray.common.msg.ResponseCode;
import me.flyray.common.util.CurrencyUtils;
import me.flyray.common.util.SnowFlake;
import me.flyray.crm.core.entity.*;
import me.flyray.crm.core.mapper.*;
import me.flyray.crm.facade.request.FreezeRequest;
import me.flyray.crm.facade.request.UnfreezeRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import me.flyray.common.enums.AccountState;
import me.flyray.common.enums.CustomerType;
import me.flyray.common.util.EntityUtils;
import me.flyray.common.util.MD5;

/**
 * 冻结、解冻相关的接口
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class CustomerFreezeOrUnfreezeBiz {
	
	private static final Logger log = LoggerFactory.getLogger(CustomerFreezeOrUnfreezeBiz.class);

	@Autowired
	private CustomerBaseMapper customerBaseMapper;
	@Autowired
	private PersonalBillingMapper personalBillingMapper;
	@Autowired
	private MerchantAccountJournalMapper merchantAccountJournalMapper;
	@Autowired
	private MerchantAccountMapper merchantAccountMapper;
	@Autowired
	private FreezeJournalMapper freezeJournalMapper;
	@Autowired
	private UnfreezeJournalMapper unfreezeJournalMapper;
	@Autowired
	private PersonalAccountMapper personalAccountMapper;
	@Value("${crm.account.balanceSaltValue}")
	private String balanceSaltValue;
	/**
	 * 冻结接口接口
	 * 若是商户 
	 * 1.商户账户余额扣除，冻结金额增加
	 * 2.新增冻结流水记录
	 * 若是个人
	 * 1.个人账户余额扣除，冻结金额增加
	 * 2.新增冻结流水记录
	 */
	public FreezeJournal freeze(FreezeRequest freezeRequest) {
		log.info("冻结接口-请求参数：{}" + EntityUtils.beanToMap(freezeRequest));
        String freezeId =String.valueOf(SnowFlake.getId());
		FreezeJournal freezeJournal=new FreezeJournal();
		//查询客户信息中的商户号和个人编号
		CustomerBase customerBase = new CustomerBase();
		customerBase.setPlatformId(freezeRequest.getPlatformId());
		customerBase.setCustomerId(freezeRequest.getCustomerId());
		customerBase = customerBaseMapper.selectOne(customerBase);

		if(freezeRequest.getCustomerType().equals(CustomerType.CUST_MERCHANT.getCode())){
			MerchantAccount queryMerchantAccount=new MerchantAccount();
			queryMerchantAccount.setPlatformId(freezeRequest.getPlatformId());
			queryMerchantAccount.setMerchantId(customerBase.getMerchantId());
			queryMerchantAccount.setMerchantType(freezeRequest.getMerchantType());
			queryMerchantAccount.setAccountType(freezeRequest.getAccountType());
			MerchantAccount merchantAccount= merchantAccountMapper.selectOne(queryMerchantAccount);
			if(null!=merchantAccount&&merchantAccount.getStatus().equals(AccountState.normal.getCode())){
				if(!MD5.sign(CurrencyUtils.decimaltoString(merchantAccount.getAccountBalance()), balanceSaltValue, "utf-8").equals(merchantAccount.getCheckSum())){
					log.info("冻结接口 返回参数。。。。。。{}", merchantAccount);
					throw new BusinessException(ResponseCode.VERIFY_ACC_AMT);
				}
				//校验商户账户余额是否充足 和余额加密值的校验
				//商户账户余额不足
				if(merchantAccount.getAccountBalance().compareTo(new BigDecimal(freezeRequest.getFreezeAmt()))<0){
					throw new BusinessException(ResponseCode.MER_ACC_BALANCE_NOT_ENOUGH);
				}
				merchantAccount.setAccountBalance(merchantAccount.getAccountBalance().subtract(new BigDecimal(freezeRequest.getFreezeAmt())));
				merchantAccount.setCheckSum(MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
				merchantAccount.setFreezeBalance(merchantAccount.getFreezeBalance().add(new BigDecimal(freezeRequest.getFreezeAmt())));
				merchantAccountMapper.updateByPrimaryKeySelective(merchantAccount);
			}else{
				log.info("冻结接口--商户账户不存在或者被冻结");
				throw new BusinessException(ResponseCode.MER_ACC_NOTEXIST);
			}
			freezeJournal.setCustomerNo(freezeRequest.getMerchantId());
		}
		if(freezeRequest.getCustomerType().equals(CustomerType.CUST_PERSONAL.getCode())){
			PersonalAccount queryPersonalAccount = new PersonalAccount();
			queryPersonalAccount.setPlatformId(freezeRequest.getPlatformId());
			queryPersonalAccount.setPersonalId(customerBase.getPersonalId());
			queryPersonalAccount.setAccountType(freezeRequest.getAccountType());
			PersonalAccount personalAccount = personalAccountMapper.selectOne(queryPersonalAccount);
			if(null!=personalAccount&&personalAccount.getStatus().equals(AccountState.normal.getCode())){
				if(!MD5.sign(CurrencyUtils.decimaltoString(personalAccount.getAccountBalance()), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())){
					log.info("冻结接口--个人账户余额不匹配");
					throw new BusinessException(ResponseCode.VERIFY_ACC_AMT);
				}
				if(personalAccount.getAccountBalance().compareTo(new BigDecimal(freezeRequest.getFreezeAmt()))<0){
					throw new BusinessException(ResponseCode.PER_ACC_BALANCE_NOT_ENOUGH);
				}
				personalAccount.setAccountBalance(personalAccount.getAccountBalance().subtract(new BigDecimal(freezeRequest.getFreezeAmt())));
				personalAccount.setCheckSum(MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
				personalAccount.setFreezeBalance(personalAccount.getFreezeBalance().add(new BigDecimal(freezeRequest.getFreezeAmt())));
				personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
			}else{
				log.info("发起退款时 冻结资金--个人账户不存在或者被冻结");
				throw new BusinessException(ResponseCode.PER_ACC_NOTEXIST);
			}
			freezeJournal.setCustomerNo(freezeRequest.getPersonalId());
		}

		freezeJournal.setJournalId(freezeId);
		freezeJournal.setPlatformId(freezeRequest.getPlatformId());
		freezeJournal.setCustomerType(freezeRequest.getCustomerType());
		freezeJournal.setCustomerNo(customerBase.getMerchantId());
		//交易类型（支付:01，退款:02，提现:03，充值:04）
		freezeJournal.setTradeType(freezeRequest.getTradeType());
		freezeJournal.setOrderNo(freezeRequest.getOrderNo());
		freezeJournal.setFreezeBalance(new BigDecimal(freezeRequest.getFreezeAmt()));
		//冻结状态 1：已冻结  2：部分解冻  3：已解冻
		freezeJournal.setStatus(FreezeStatus.freeze.getCode());
		freezeJournal.setCreateTime(new Date());
		freezeJournalMapper.insertSelective(freezeJournal);
		return freezeJournal;
	}
	
	/**
	 * 解冻接口
	 * 若是商户
	 * 1.商户账户冻结金额扣除，商户账户余额增加。 
	 * 2.新增解冻流水记录
	 * 若是个人
	 * 1.个人账户冻结金额扣除，个人账户余额增加。 
	 * 2.新增解冻流水记录
	 */
	public UnfreezeJournal unfreeze(UnfreezeRequest unFreezeRequest) {
		log.info("退款失败时 解冻资金的接口 -请求参数：{}" + EntityUtils.beanToMap(unFreezeRequest));
		Map<String, Object> response = new HashMap<String, Object>();

		//查询客户信息中的商户号和个人编号
		CustomerBase customerBase = new CustomerBase();
		customerBase.setPlatformId(unFreezeRequest.getPlatformId());
		customerBase.setCustomerId(unFreezeRequest.getCustomerId());
		customerBase = customerBaseMapper.selectOne(customerBase);

		/**
		 * 根据冻结流水号查询是否被解冻
		 * */
		UnfreezeJournal queryUnfreezeJournal = new UnfreezeJournal();
		queryUnfreezeJournal.setFreezeId(unFreezeRequest.getFreezeId());
		queryUnfreezeJournal.setOrderNo(unFreezeRequest.getOrderNo());
		UnfreezeJournal unfreezeJournal=unfreezeJournalMapper.selectOne(queryUnfreezeJournal);
		if(null!=unfreezeJournal){
			log.info("解冻接口--冻结资金已解冻");
			throw new BusinessException(BizResponseCode.UNFREEZE_IS_EXIST.getCode());
		}
		if(unFreezeRequest.getCustomerType().equals(CustomerType.CUST_MERCHANT.getCode())){
			MerchantAccount queryMerchantAccount=new MerchantAccount();
			queryMerchantAccount.setPlatformId(unFreezeRequest.getPlatformId());
			queryMerchantAccount.setMerchantId(customerBase.getMerchantId());
			queryMerchantAccount.setMerchantType(unFreezeRequest.getMerchantType());
			queryMerchantAccount.setAccountType(unFreezeRequest.getAccountType());
			MerchantAccount merchantAccount= merchantAccountMapper.selectOne(queryMerchantAccount);
			if(null!=merchantAccount&&merchantAccount.getStatus().equals(AccountState.normal.getCode())){
				if(!MD5.sign(CurrencyUtils.decimaltoString(merchantAccount.getAccountBalance()), balanceSaltValue, "utf-8").equals(merchantAccount.getCheckSum())){
					log.info("冻结接口 返回参数。。。。。。{}", response);
					throw new BusinessException(BizResponseCode.MER_ACC_BALANCE_NOT_MATE.getCode());
				}
				//校验商户账户余额是否充足 和余额加密值的校验
				//商户账户余额不足
				if(merchantAccount.getFreezeBalance().compareTo(new BigDecimal(unFreezeRequest.getUnfreezeAmt()))<0){
					log.info("冻结接口 返回参数。。。。。。{}", response);
					throw new BusinessException(BizResponseCode.MER_ACC_BALANCE_NOT_ENOUGH.getCode());
				}
				merchantAccount.setAccountBalance(merchantAccount.getAccountBalance().add(new BigDecimal(unFreezeRequest.getUnfreezeAmt())));
				merchantAccount.setCheckSum(MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
				merchantAccount.setFreezeBalance(merchantAccount.getFreezeBalance().subtract(new BigDecimal(unFreezeRequest.getUnfreezeAmt())));
				merchantAccountMapper.updateByPrimaryKeySelective(merchantAccount);
			}else{
				log.info("冻结接口 返回参数。。。。。。{}", response);
				throw new BusinessException(BizResponseCode.MER_ACC_NOTEXIST.getCode());
			}
		}
		if(unFreezeRequest.getCustomerType().equals(CustomerType.CUST_PERSONAL.getCode())){
			PersonalAccount queryPersonalAccount = new PersonalAccount();
			queryPersonalAccount.setPlatformId(unFreezeRequest.getPlatformId());
			queryPersonalAccount.setPersonalId(customerBase.getPersonalId());
			queryPersonalAccount.setAccountType(unFreezeRequest.getAccountType());
			PersonalAccount personalAccount = personalAccountMapper.selectOne(queryPersonalAccount);
			if(null!=personalAccount&&personalAccount.getStatus().equals(AccountState.normal.getCode())){
				if(!MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())){
					log.info("冻结接口。。。。。。{}", response);
					throw new BusinessException(BizResponseCode.MER_ACC_NOTEXIST.getCode());
				}
				personalAccount.setAccountBalance(personalAccount.getAccountBalance().add(new BigDecimal(unFreezeRequest.getUnfreezeAmt())));
				personalAccount.setCheckSum(MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
				personalAccount.setFreezeBalance(personalAccount.getFreezeBalance().subtract(new BigDecimal(unFreezeRequest.getUnfreezeAmt())));
				personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
			}else{
				log.info("发起退款时 冻结资金--个人账户不存在或者被冻结");
				throw new BusinessException(BizResponseCode.PER_ACC_NOTEXIST.getCode());
			}
		}
		queryUnfreezeJournal.setJournalId(String.valueOf(SnowFlake.getId()));
		queryUnfreezeJournal.setTradeType(unFreezeRequest.getTradeType());
		queryUnfreezeJournal.setUnfreezeBalance(new BigDecimal(unFreezeRequest.getUnfreezeAmt()));
		queryUnfreezeJournal.setCreateTime(new Date());
		unfreezeJournalMapper.insertSelective(queryUnfreezeJournal);
		return queryUnfreezeJournal;
	}
}
